package com.cennavi.minemap.service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.client.ClientProtocolException;
import org.geojson.LineString;
import org.geojson.LngLatAlt;
import org.geojson.Point;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cennavi.minemap.util.HttpClientUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

@Service
@ComponentScan(basePackages = { "com.cennavi.minemap.util" })
@PropertySource(value = { "classpath:application.properties" })
public class WEBTService {
	@Value("${spring.service.wbt.url}")
	private String routeUrl;
	
	@Value("${spring.service.wbt.searchurl}")
	private String url;

	private static ObjectMapper m_objMapper = new ObjectMapper();
	
	//Logger logger = LoggerFactory.getLogger(WEBTService.class);
	
	public String getAdNameByAdCode(String adCode) throws ClientProtocolException, IOException{
		String token = "1";
		String allUrl = url + token + "/gis/metadataquery/adcode.json?adcode=" + adCode;
		
		String response = HttpClientUtil.doGet(allUrl);
		JSONObject object = JSONObject.parseObject(response).getJSONObject("response");
		JSONObject result = object.getJSONObject("result");
		
		JSONArray adcodelist = result.getJSONArray("adcodelist");
		
		JSONObject adcodeObject = adcodelist.getJSONObject(0);
		
		return adcodeObject.getString("name");
	}
	

	/**
	 * 1.1 keyword
	 * 
	 * @param token
	 * @param adcode
	 * @param key
	 * @param searchType
	 * @param dataType
	 * @param pageNumber
	 * @param pageCount
	 * @param source
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public String keyword(String token, String adcode, String key, String searchType, String dataType,
			Integer pageNumber, Integer pageCount) throws ClientProtocolException, IOException {

		String allUrl = url + token + "/gis/keyquery.json?key=" + key + "&language=0";

		if (adcode != null) {
			allUrl = allUrl + "&adcode=" + adcode;
		}
		if (dataType != null) {
			allUrl = allUrl + "&datatype=" + dataType;
		}
		if (searchType != null) {
			allUrl = allUrl + "&searchtype=" + searchType;
		}
		if (pageNumber != null) {
			allUrl = allUrl + "&pageNumber=" + pageNumber;
		}
		if (pageCount != null) {
			allUrl = allUrl + "&pageCount=" + pageCount;
		}
/*
		String response = HttpClientUtil.doGet(allUrl);

		JSONObject object = JSONObject.parseObject(response).getJSONObject("response");

		JSONObject result = object.getJSONObject("result");

		JSONArray array = result.getJSONArray("keyresult");
		result.put("rows", array);
		for (int i = 0; i < array.size(); i++) {
			JSONObject row = array.getJSONObject(i);
			row.remove("apttype");
			row.remove("selectedNumber");
			row.remove("pid");
			row.remove("setedNumber");
			row.remove("score");
			
			JSONObject geom = row.getJSONObject("geom");
			
			row.put("geom", convertGeoJson(geom));
			
			JSONObject display_geom = row.getJSONObject("geom_display");
			row.put("geom_display", convertGeoJson(display_geom));
 		}

		result.remove("keyresult");

		return result.toJSONString();
		*/
		
		return dealSearchResponse(allUrl);
	}

	/**
	 * 1.2 surround
	 * 
	 * @param token
	 * @param adcode
	 * @param key
	 * @param searchType
	 * @param dataType
	 * @param pageNumber
	 * @param pageCount
	 * @param source
	 * @param location
	 * @param inRadius
	 * @param spatialfunction
	 * @param radius
	 * @param seq
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public String surround(String token, String adcode, String key, String searchType, String dataType,
			Integer pageNumber, Integer pageCount, Integer source, Double lon, Double lat, Integer inRadius,
			String spatialFunction, Integer radius, Integer seq) throws ClientProtocolException, IOException {

		String allUrl = url + token + "/gis/keyquery/surround.json?key=" + key + "&centerlon=" + lon + "&centerlat="
				+ lat + "&radius=" + radius + "&language=0";

		if (adcode != null) {
			allUrl = allUrl + "&adcode=" + adcode;
		}
		if (dataType != null) {
			allUrl = allUrl + "&datatype=" + dataType;
		}
		if (searchType != null) {
			allUrl = allUrl + "&searchtype=" + searchType;
		}
		if (pageNumber != null) {
			allUrl = allUrl + "&pageNumber=" + pageNumber;
		}
		if (pageCount != null) {
			allUrl = allUrl + "&pageCount=" + pageCount;
		}
		if (inRadius != null) {
			allUrl = allUrl + "&inradius=" + inRadius;
		}
		if (spatialFunction != null) {
			allUrl = allUrl + "&spatialfuntion=" + spatialFunction;
		}
		if (radius != null) {
			allUrl = allUrl + "&radius=" + radius;
		}
		if (seq != null) {
			allUrl = allUrl + "&seq=" + seq;
		}
/*
		String response = HttpClientUtil.doGet(allUrl);

		JSONObject object = JSONObject.parseObject(response).getJSONObject("response");

		JSONObject result = object.getJSONObject("result");

		JSONArray array = result.getJSONArray("keyresult");
		result.put("rows", array);
		for (int i = 0; i < array.size(); i++) {
			JSONObject row = array.getJSONObject(i);
			row.remove("apttype");
			row.remove("selectedNumber");
			row.remove("pid");
			row.remove("setedNumber");
			row.remove("score");
		}

		result.remove("keyresult");

		return result.toJSONString();
		*/
		return dealSearchResponse(allUrl);
	}

	/**
	 * 1.3 bbox
	 * 
	 * @param token
	 * @param adcode
	 * @param key
	 * @param searchType
	 * @param dataType
	 * @param pageNumber
	 * @param pageCount
	 * @param source
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public String bbox(String token, String adcode, String key, String searchType, String dataType, Integer pageNumber,
			Integer pageCount, Double lon1, Double lat1, Double lon2, Double lat2, Integer seq)
			throws ClientProtocolException, IOException {
		String allUrl = url + token + "/gis/keyquery/bbox.json?key=" + key + "&lon1=" + lon1 + "&lat1=" + lat1
				+ "&lon2=" + lon2 + "&lat2=" + lat2 + "&language=0";

		if (adcode != null) {
			allUrl = allUrl + "&adcode=" + adcode;
		}
		if (dataType != null) {
			allUrl = allUrl + "&datatype=" + dataType;
		}
		if (searchType != null) {
			allUrl = allUrl + "&searchtype=" + searchType;
		}
		if (pageNumber != null) {
			allUrl = allUrl + "&pageNumber=" + pageNumber;
		}
		if (pageCount != null) {
			allUrl = allUrl + "&pageCount=" + pageCount;
		}
		if (seq != null) {
			allUrl = allUrl + "&seq=" + seq;
		}
/*
		String response = HttpClientUtil.doGet(allUrl);

		JSONObject object = JSONObject.parseObject(response).getJSONObject("response");

		JSONObject result = object.getJSONObject("result");

		JSONArray array = result.getJSONArray("keyresult");
		result.put("rows", array);
		for (int i = 0; i < array.size(); i++) {
			JSONObject row = array.getJSONObject(i);
			row.remove("apttype");
			row.remove("selectedNumber");
			row.remove("pid");
			row.remove("setedNumber");
			row.remove("score");
		}
		result.remove("keyresult");

		return result.toJSONString();
		
		*/
		
		return dealSearchResponse(allUrl);
	}

	/**
	 * 2 驾车路径规划
	 * 
	 * @param token
	 * @param sPoint
	 * @param ePoint
	 * @param wayPoints
	 * @param shpFlag
	 * @param costModel
	 * @param vehicleSpeed
	 * @param numAlt
	 * @param criteria
	 * @param source
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public String driving(String token, String sPoint, String ePoint, String wayPoints, Integer shpFlag,
			Integer costModel, Integer vehicleSpeed, Integer numAlt, Integer criteria, Integer traffic)
			throws ClientProtocolException, IOException {

		String allUrl = routeUrl + token + "/gis/routequery/routequery.json?";

		String point = "";
		long slon = encodeCoord(sPoint.split(",")[0]);
		long slat = encodeCoord(sPoint.split(",")[1]);

		point = "0," + slon + "," + slat;

		if (wayPoints != null && wayPoints.trim() != null && !wayPoints.equals("")) {
			String[] coords = wayPoints.split(",");
			if (coords.length > 10) {
				return null;
			} else {
				for (int i = 0; i < coords.length - 1; i += 2) {
					point = point + ",0," + encodeCoord(coords[i]) + "," + encodeCoord(coords[i + 1]);
				}
			}
		}

		long elon = encodeCoord(ePoint.split(",")[0]);
		long elat = encodeCoord(ePoint.split(",")[1]);

		point = point + ",0," + elon + "," + elat;

		allUrl = allUrl + "point=" + point;

		if (shpFlag != null) {
			allUrl = allUrl + "&shpflag=" + shpFlag;
		}
		if (costModel != null) {
			allUrl = allUrl + "&costModel=" + costModel;
		}
		if (vehicleSpeed != null) {
			allUrl = allUrl + "&vehicleSpeed=" + vehicleSpeed;
		}
		if (numAlt != null) {
			allUrl = allUrl + "&numAlt=" + numAlt;
		}
		if (criteria != null) {
			allUrl = allUrl + "&criteria=" + criteria;
		}

		//long stime = new Date().getTime();
		//logger.info("driving start request : " + stime);
		String response = HttpClientUtil.doGet(allUrl);

		//long etime = new Date().getTime();
		
		//logger.info("driving request time ：" + (etime - stime) + "\tURL=" + allUrl);
		
		JSONObject object = JSONObject.parseObject(response).getJSONObject("response");

		JSONObject result = object.getJSONObject("result");

		JSONArray array = result.getJSONArray("routeInfo");
		
		for (int i = 0; i < array.size(); i++) {
			JSONObject row = array.getJSONObject(i);
			/*
			String envelope = row.getString("envelope");
			String[] coordArray = envelope.split(",");
			JSONArray ps = new JSONArray();
			for (int j = 0; j < coordArray.length - 1 ; j+= 2) {
				JSONArray p = new JSONArray();
				p.add(decodeCoord(coordArray[i]));
				p.add(decodeCoord(coordArray[i+1]));
				ps.add(p);
			}
			row.put("envelope", ps);*/
			JSONObject endPoint = row.getJSONObject("endPoint");
			JSONObject geom = endPoint.getJSONObject("geometry");
			endPoint.put("geometry", convertGeoJson(geom));
			row.put("endPoint", endPoint);
			
			row.remove("envelop");
			row.remove("clist1cnt");
			row.remove("clist1");
			row.remove("clist2cnt");
			row.remove("clist2");
			row.remove("via1side");
			row.remove("via1distance");
			row.remove("via2side");
			row.remove("via2distance");
			row.remove("via3side");
			row.remove("via3distance");
			row.remove("via4side");
			row.remove("via4distance");
			row.remove("via5side");
			row.remove("via5distance");
			row.remove("via6side");
			row.remove("via6distance");
			
			JSONArray jsonArray = row.getJSONArray("segmt");
			for (int j = 0; j < jsonArray.size(); j++){
				JSONObject jsonObject = jsonArray.getJSONObject(j);
				jsonObject.remove("addinfo");
				jsonObject.remove("passinfo");
				
				JSONObject clist = jsonObject.getJSONObject("clist");
				
				JSONObject geometry = clist.getJSONObject("geometry");
				clist.put("geometry", convertGeoJson(geometry));
				jsonObject.put("clist", clist);
				if (traffic == 1) {
					////////////////返回支持路况的路径分段
					String jamlist = jsonObject.getString("jamlist");
					String linkshpidxlist = jsonObject.getString("linkshpidxlist");
					JSONObject collection = convertClist(jamlist, linkshpidxlist, clist);
					jsonObject.put("clisttraffic", collection);
				}
			}
			
			row.put("segmt", jsonArray);
		}
		
		result.put("rows", array);
		result.remove("routeInfo");

		//long rtime = new Date().getTime();
		//logger.info("driving response return : " + rtime);
		//logger.info("response deal time :" + (rtime - etime) + "\tURL=" + allUrl);
		
		return result.toJSONString();
	}

	/**
	 * 3 公交路径规划
	 * 
	 * @param token
	 * @param acode
	 * @param strategy
	 * @param shpInfoFlag
	 * @param sPoint
	 * @param ePoint
	 * @param showWalkInfo
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public String busTransfer(String token, String adCode, Integer strategy, Integer shpInfoFlag, String sPoint,
			String ePoint, Integer showWalkInfo) throws ClientProtocolException, IOException {

		String allUrl = routeUrl + token + "/gis/busquery/bustransferquery.json?acode=" + adCode;

		long slon = encodeCoord(sPoint.split(",")[0]);
		long slat = encodeCoord(sPoint.split(",")[1]);
		long elon = encodeCoord(ePoint.split(",")[0]);
		long elat = encodeCoord(ePoint.split(",")[1]);

		allUrl = allUrl + "&spx=" + slon + "&spy=" + slat + "&epx=" + elon + "&epy=" + elat;

		if (strategy != null) {
			allUrl = allUrl + "&strategy=" + strategy;
		}
		if (shpInfoFlag != null) {
			allUrl = allUrl + "&shpinfoflag=" + shpInfoFlag;
		}
		if (showWalkInfo != null) {
			allUrl = allUrl + "&showwalkinfo=" + showWalkInfo;
		}

		String response = HttpClientUtil.doGet(allUrl);

		JSONObject object = JSONObject.parseObject(response).getJSONObject("response");

		JSONObject result = object.getJSONObject("result");

		JSONArray array = result.getJSONArray("busInfo");

		for (int i = 0; i < array.size(); i++) {
			JSONObject row = array.getJSONObject(i);
			String toDistLine = row.getString("toDistLine");
			
			JSONObject toDistLineObj = new JSONObject();
			
			if(toDistLine == null){
				row.put("toDistLine", null);
			}
			else{
				toDistLineObj.put("geometry", decodeListCoord(toDistLine));
				row.put("toDistLine", toDistLineObj);
			}

			JSONArray lineInfos = row.getJSONArray("lineInfo");
			for (int j = 0; j < lineInfos.size(); j++) {
				JSONObject lineInfo = lineInfos.getJSONObject(j);
				String clist = lineInfo.getString("clist");
				if (clist != null) {
					JSONObject lineObj = new JSONObject();
					lineObj.put("geometry", decodeListCoord(clist));
					//lineInfo.put("clist", decodeListCoord(clist));
					lineInfo.put("clist", lineObj);
				}
				String walkLine = lineInfo.getString("walkLine");
				if (walkLine != null) {
					JSONObject walkLineObj = new JSONObject();
					walkLineObj.put("geometry", decodeListCoord(walkLine));
					//lineInfo.put("walkLine", decodeListCoord(walkLine));
					lineInfo.put("walkLine", walkLineObj);
				}
                
				JSONObject sstopObj = new JSONObject();
				sstopObj.put("geometry",
						JSONObject.parseObject(m_objMapper
								.writeValueAsString(new Point(new LngLatAlt(decodeCoord(lineInfo.getString("spx")),
										decodeCoord(lineInfo.getString("spy")))))));
				lineInfo.put("sstop", sstopObj);
				
				JSONObject estopObj = new JSONObject();
				estopObj.put("geometry",
						JSONObject.parseObject(m_objMapper
								.writeValueAsString(new Point(new LngLatAlt(decodeCoord(lineInfo.getString("epx")),
										decodeCoord(lineInfo.getString("epy")))))));
				
				lineInfo.put("estop", estopObj);
				
				lineInfo.remove("spx");
				lineInfo.remove("spy");
				lineInfo.remove("epx");
				lineInfo.remove("epy");
			}
		}

		result.put("rows", array);
		result.remove("busInfo");

		return result.toJSONString();
	}

	/**
	 * 4.查找中心点所在行政区划
	 * 
	 * @param token
	 * @param lon
	 * @param lat
	 * @param geometry
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public String adminByPoint(String token, Double lon, Double lat, Integer geometry, Integer language)
			throws ClientProtocolException, IOException {
		String allUrl = url + token + "/gis/reversegeocoding/adminbypoint.json?lon=" + lon + "&lat=" + lat
				+ "&language=" + language;

		if (geometry != null) {
			allUrl = allUrl + "&geometry=" + geometry;
		}

		String response = HttpClientUtil.doGet(allUrl);

		JSONObject object = JSONObject.parseObject(response).getJSONObject("response");

		JSONObject result = object.getJSONObject("result");

		return result.toJSONString();
	}

	/**
	 * 5.geocoding
	 * 
	 * @param token
	 * @param address
	 * @param adcode
	 * @param source
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 *             http://host:port/fkgis-gateway/{token}/geocodingquery/geo.(
	 *             json|xml)?provice={province}&city={city}&distict={county}&
	 *             querystr={address}&adcode={adcode}
	 */
	public String geocoding(String token, String address, String adcode) throws ClientProtocolException, IOException {
		String response = HttpClientUtil
				.doGet(url + token + "/gis/geocodingquery/geo.json?querystr=" + address + "&adcode=" + adcode);

		JSONObject object = JSONObject.parseObject(response).getJSONObject("response");

		JSONObject result = object.getJSONObject("result");

		JSONArray array = result.getJSONArray("geoPointList");
		result.put("rows", array);
		result.remove("geoPointList");

		return result.toJSONString();
	}

	/**
	 * 6.reveserGeocoding
	 * 
	 * @param token
	 * @param lon
	 * @param lat
	 * @param type
	 * @param radius
	 * @param roadRadius
	 * @param kind
	 * @param source
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public String reverseGeocoding(String token, Double lon, Double lat, Integer type, Integer radius,
			Integer roadRadius, Integer kind) throws ClientProtocolException, IOException {
		String allUrl = url + token + "/gis/reversegeocoding.json?lon=" + lon + "&lat=" + lat + "&language=0";

		if (type != null) {
			allUrl = allUrl + "&type=" + type;
		}
		if (radius != null) {
			allUrl = allUrl + "&radius=" + radius;
		}
		if (roadRadius != null) {
			allUrl = allUrl + "&roadradius=" + roadRadius;
		}
		if (kind != null) {
			allUrl = allUrl + "&kind=" + kind;
		}

		String response = HttpClientUtil.doGet(allUrl);

		JSONObject object = JSONObject.parseObject(response).getJSONObject("response");

		JSONObject result = object.getJSONObject("result");

		return result.toJSONString();
	}

	/**
	 * 7.周边查找
	 * 
	 * @param token
	 * @param lon
	 * @param lat
	 * @param type
	 * @param radius
	 * @param count
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public String around(String token, Double lon, Double lat, String type, Integer radius, Integer count)
			throws ClientProtocolException, IOException {
		String allUrl = url + token + "/gis/reversegeocoding/poiaround.json?lon=" + lon + "&lat=" + lat
				+ "&language=0&type=" + type;

		if (radius != null) {
			allUrl = allUrl + "&radius=" + radius;
		}
		if (count != null) {
			allUrl = allUrl + "&count=" + count;
		}
		String response = HttpClientUtil.doGet(allUrl);
		JSONObject object = JSONObject.parseObject(response).getJSONObject("response");

		JSONObject result = object.getJSONObject("result");

		JSONArray array = result.getJSONArray("list");
		result.put("rows", array);
		result.remove("list");

		return result.toJSONString();
	}
	/**
	 * 8.智能提示
	 * 
	 * @param token
	 * @param input
	 * @param adCode
	 * @param searchType
	 * @param pageCount
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public String smartTips(String token, String input, int adCode , String searchType , Integer pageCount) throws ClientProtocolException , IOException{
		String allUrl = routeUrl + token + "/gis/smarttips.json?inputstr=" + input + "&adcode=" + adCode;
		if (searchType != null){
			allUrl = allUrl + "&searchtype=" + searchType;
		}
		
		if (pageCount != null){
			allUrl = allUrl + "&pageCount=" + pageCount;
		}
		
		String response = HttpClientUtil.doGet(allUrl);
		JSONObject object = JSONObject.parseObject(response).getJSONObject("response");
		JSONObject result = object.getJSONObject("result");
		JSONArray array = result.getJSONArray("infoList");
		result.put("rows", array);
		result.remove("infoList");
		
		return result.toJSONString();
	}

	public static long encodeCoord(String input) {
		return Math.round(Double.parseDouble(input.trim()) * 3600 * 128);
	}

	public static Double decodeCoord(String input) {
		return Math.round((Double.parseDouble(input.trim()) / 3600 / 128) * 1000000) / 1000000d;
	}

	public static JSONObject decodeListCoord(String input) {
		LineString line = new LineString();
		String[] coordArray = input.split(",");
		//String rCoord = "";
		// for(String coord : coordArray){
		// rCoord = rCoord + decodeCoord(coord) + ",";
		// }

		for (int i = 0; i < coordArray.length - 1; i += 2) {
			line.add(new LngLatAlt(decodeCoord(coordArray[i]), decodeCoord(coordArray[i + 1])));
		}

		String rString = "";

		try {
			rString = m_objMapper.writeValueAsString(line);
		} catch (JsonProcessingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return JSONObject.parseObject(rString);
	}
	
	public String dealSearchResponse(String url) throws IOException{
		String response = HttpClientUtil.doGet(url);

		JSONObject object = JSONObject.parseObject(response).getJSONObject("response");

		JSONObject result = object.getJSONObject("result");

		JSONArray array = result.getJSONArray("keyresult");
		result.put("rows", array);
		for (int i = 0; i < array.size(); i++) {
			JSONObject row = array.getJSONObject(i);
			row.remove("apttype");
			row.remove("selectedNumber");
			row.remove("pid");
			row.remove("setedNumber");
			row.remove("score");
			
			JSONObject geom = row.getJSONObject("geom");
			
			row.put("geom", convertGeoJson(geom));
			
			JSONObject display_geom = row.getJSONObject("geom_display");
			row.put("geom_display", convertGeoJson(display_geom));
 		}

		result.remove("keyresult");

		return result.toJSONString();
	}
	
	public static JSONObject convertGeoJson(JSONObject obj){
		if (obj == null){
			return null;
		}
		String type = obj.getString("type");
		
		JSONArray array = obj.getJSONArray("coordinates");
		if (array == null){
			return null;
		}
		
		List<List<String>> list = new ArrayList<List<String>>();
		for (int i = 0 ; i < array.size() ; i++){
			JSONArray jsonArray = array.getJSONArray(i);
			List<String> coordinate = new ArrayList<String>();
			for(int j = 0; j < jsonArray.size(); j++){
				String coor = jsonArray.getString(j);
				coordinate.add(coor);
			}
			list.add(coordinate);
		}
		
		String rString = "";
		if (type.equals("Point")){
			if (list.size() != 1){
				return null;
			}
			List<String> point = list.get(0);
			
			if (point.size() != 2){
				return null;
			}
			
			try {
				rString = m_objMapper.writeValueAsString(new Point(new LngLatAlt(Double.parseDouble(point.get(0)),Double.parseDouble(point.get(1)))));
			} catch (NumberFormatException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (JsonProcessingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		else if (type.equals("LineString")){
			if (list.size() < 2){
				return null;
			}
			LineString line = new LineString();
			for (int i = 0; i < list.size(); i++){
				List<String> point = list.get(i);
				
				if (point.size() != 2){
					continue;
				}
				
				line.add(new LngLatAlt(Double.parseDouble(point.get(0)),Double.parseDouble(point.get(1))));
			}
			
			try {
				rString = m_objMapper.writeValueAsString(line);
			} catch (JsonProcessingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		return JSONObject.parseObject(rString);
	}
	
	public JSONObject convertClist(String jamlist , String linkshpidxlist , JSONObject clist){
		JSONObject retObject = new JSONObject();
		
		retObject.put("type", "FeatureCollection");
		JSONArray  featureArr = new JSONArray();
		
		if (jamlist == null || linkshpidxlist == null){
			JSONObject feature = new JSONObject();
			feature.put("type", "Feature");
			JSONObject geom = clist.getJSONObject("geometry");
			JSONObject geometry = convertGeoJson(geom);
			feature.put("geometry", geometry);
			
			JSONObject properties = new JSONObject();
			properties.put("traffic", 0);
			feature.put("properties", properties);
			
			featureArr.add(feature);
		}else{
			String[] jams = jamlist.split(",");
			String[] shpidxs = linkshpidxlist.split(",");
			
			if (jams.length != shpidxs.length){
				JSONObject feature = new JSONObject();
				feature.put("type", "Feature");
				JSONObject geom = clist.getJSONObject("geometry");
				JSONObject geometry = convertGeoJson(geom);
				feature.put("geometry", geometry);
				
				JSONObject properties = new JSONObject();
				properties.put("traffic", 0);
				feature.put("properties", properties);
				
				featureArr.add(feature);
				
			}else{
				int isize = jams.length;
				int preTraffic = -1;
				
				List<List<Double>> geomlist = convertObject(clist);
				
				List<LngLatAlt> line_coord = new ArrayList<>();
				for(int i = 0 ; i < isize ; i++){
					String straffic = jams[i];
					
					int start = Integer.parseInt(shpidxs[i]);
					int end = geomlist.size() -1;
					if (i + 1 <= isize - 1){
						end = Integer.parseInt(shpidxs[i + 1]);
					}
					int traffic = Integer.parseInt(straffic.substring(0, 1));
					if (traffic == 0 || traffic == 7){
						traffic = 1;
					}
					if (preTraffic != traffic){
						if (line_coord.size() > 0){
							LineString line = new LineString();
							line.setCoordinates(line_coord);
							try {
								String strLine = m_objMapper.writeValueAsString(line);
								JSONObject geometry = JSONObject.parseObject(strLine);
								
								JSONObject feature = new JSONObject();
								feature.put("type", "Feature");
								
								feature.put("geometry", geometry);
								
								JSONObject properties = new JSONObject();
								properties.put("traffic", preTraffic);
								feature.put("properties", properties);
								
								featureArr.add(feature);
								
							} catch (JsonProcessingException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
						}
						
						line_coord.clear();
					}
					
					preTraffic = traffic;
					for (int j = start ; j <= end ; j++){
						List<Double> coord_p = geomlist.get(j);
						LngLatAlt point = new LngLatAlt(coord_p.get(0) , coord_p.get(1));
						if (line_coord.size() > 0 && j == start){
							continue;
						}
						line_coord.add(point);
					}
				}
				
				if (line_coord.size() > 0){
					LineString line = new LineString();
					line.setCoordinates(line_coord);
					try {
						String strLine = m_objMapper.writeValueAsString(line);
						JSONObject geometry = JSONObject.parseObject(strLine);
						
						JSONObject feature = new JSONObject();
						feature.put("type", "Feature");
						
						feature.put("geometry", geometry);
						
						JSONObject properties = new JSONObject();
						properties.put("traffic", preTraffic);
						feature.put("properties", properties);
						
						featureArr.add(feature);
						
					} catch (JsonProcessingException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
		retObject.put("features", featureArr);
		return retObject;
	}
	
	public List<List<Double>> convertObject(JSONObject obj){
		if (obj == null){
			return null;
		}
		
		JSONObject geom = obj.getJSONObject("geometry");
		//String type = geom.getString("type");
		
		JSONArray array = geom.getJSONArray("coordinates");
		if (array == null){
			return null;
		}
		
		List<List<Double>> list = new ArrayList<>();
		for (int i = 0 ; i < array.size() ; i++){
			JSONArray jsonArray = array.getJSONArray(i);
			List<Double> coordinate = new ArrayList<>();
			for(int j = 0; j < jsonArray.size(); j++){
				String coor = jsonArray.getString(j);
				coordinate.add(Double.parseDouble(coor));
			}
			list.add(coordinate);
		}
        
		return list;
	}
}
